﻿using MassTransit;

class Program
{
    static async Task Main(string[] args)
    {
        IBusControl busControl = null;

        try
        {
            busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                cfg.Host(new Uri("rabbitmq://124.221.160.244:5672"), h =>
                {
                    h.Username("ll");
                    h.Password("123456");
                });

                // 接收端点
                cfg.ReceiveEndpoint("appA_queue", e =>
                {
                    e.Consumer<MessageConsumer>();
                });
            });

            // 设置启动超时时间
            var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // 5秒超时
            try
            {
                await busControl.StartAsync(cts.Token);
                Console.WriteLine("App A is running. Press Enter to send a message to App B.");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Failed to start bus: Timeout exceeded.");
                return; // 退出程序
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to start bus: {ex.Message}");
                return; // 退出程序
            }

            while (true)
            {
                Console.ReadLine();
                try
                {
                    await busControl.Publish(new Message { Content = "Hello from App A!" });
                    Console.WriteLine("Message sent successfully.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to send message: {ex.Message}");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to start bus: {ex.Message}");
        }
        finally
        {
            if (busControl != null)
            {
                await busControl.StopAsync();
            }
        }
    }
}

public class MessageConsumer : IConsumer<Message>
{
    public Task Consume(ConsumeContext<Message> context)
    {
        Console.WriteLine($"App A received message: {context.Message.Content}");
        return Task.CompletedTask;
    }
}

public class Message
{
    public string Content { get; set; }
}

//MilvusClient milvusClient = new MilvusClient("localhost");
//MilvusHealthState ishealthresult = await milvusClient.HealthAsync();


//string collectionName = "book";
//MilvusCollection collection = milvusClient.GetCollection(collectionName);

////Check if this collection exists
//var hasCollection = await milvusClient.HasCollectionAsync(collectionName);

//if (hasCollection)
//{
//    await collection.DropAsync();
//    Console.WriteLine("Drop collection {0}", collectionName);
//}

//await milvusClient.CreateCollectionAsync(
//            collectionName,
//            new[] {
//                FieldSchema.Create<long>("book_id", isPrimaryKey:true),
//                FieldSchema.Create<long>("word_count"),
//                FieldSchema.CreateVarchar("book_name", 256),
//                FieldSchema.CreateFloatVector("book_intro", 2)
//            }
//        );

//Random ran = new();
//List<long> bookIds = new();
//List<long> wordCounts = new();
//List<ReadOnlyMemory<float>> bookIntros = new();
//List<string> bookNames = new();
//for (long i = 0L; i < 2000; ++i)
//{
//    bookIds.Add(i);
//    wordCounts.Add(i + 10000);
//    bookNames.Add($"Book Name {i}");

//    float[] vector = new float[2];
//    for (int k = 0; k < 2; ++k)
//    {
//        vector[k] = ran.Next();
//    }
//    bookIntros.Add(vector);
//}

//MilvusCollection collection = milvusClient.GetCollection(collectionName);

//MutationResult result = await collection.InsertAsync(
//    new FieldData[]
//    {
//        FieldData.Create("book_id", bookIds),
//        FieldData.Create("word_count", wordCounts),
//        FieldData.Create("book_name", bookNames),
//        FieldData.CreateFloatVector("book_intro", bookIntros),
//    });

//// Check result
//Console.WriteLine("Insert count:{0},", result.InsertCount);


//MilvusCollection collection = milvusClient.GetCollection(collectionName);
//await collection.CreateIndexAsync(
//    "book_intro",
//    //MilvusIndexType.IVF_FLAT,//Use MilvusIndexType.IVF_FLAT.
//    IndexType.AutoIndex,//Use MilvusIndexType.AUTOINDEX when you are using zilliz cloud.
//    SimilarityMetricType.L2);

//// Check index status
//IList<MilvusIndexInfo> indexInfos = await collection.DescribeIndexAsync("book_intro");

//foreach (var info in indexInfos)
//{
//    Console.WriteLine("FieldName:{0}, IndexName:{1}, IndexId:{2}", info.FieldName, info.IndexName, info.IndexId);
//}

//// Then load it
//await collection.LoadAsync();
//List<string> search_output_fields = new() { "book_id" };
//List<List<float>> search_vectors = new() { new() { 0.1f, 0.2f } };
//SearchResults searchResult = await collection.SearchAsync(
//    "book_intro",
//    new ReadOnlyMemory<float>[] { new[] { 0.1f, 0.2f } },
//    SimilarityMetricType.L2,
//    limit: 2);

//// Query
//string expr = "book_id in [2,4,6,8]";

//QueryParameters queryParameters = new();
//queryParameters.OutputFields.Add("book_id");
//queryParameters.OutputFields.Add("word_count");
//// 创建一个 Stopwatch 实例
//Stopwatch stopwatch = new Stopwatch();

//// 开始计时
//stopwatch.Start();
//IReadOnlyList<FieldData> queryResult = await collection.QueryAsync(
//    expr,
//    queryParameters);

//// 停止计时
//stopwatch.Stop();
// Ollama 本地模型配置
//var modelId = "deepseek-r1:1.5b"; // 你的 Ollama 模型名称
//var endpoint = "http://127.0.0.1:11434"; // Ollama API 地址
//var apiKey = ""; // Ollama 通常不需要 API Key，可留空

//// 使用 OpenAI 兼容接口连接 Ollama
//var builder = Kernel.CreateBuilder().AddOllamaTextEmbeddingGeneration(modelId, endpoint, apiKey)
//    .AddOllamaChatCompletion(modelId, endpoint, apiKey);

//// 日志和其他配置
//builder.Services.AddLogging(services => services.AddConsole().SetMinimumLevel(LogLevel.Error));
//builder.Services.AddHttpClient(); // 此行现在可以正常工作

//// 构建 kernel
//Kernel kernel = builder.Build();
//var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

//// 获取 embedding
//string text = "华为给我增智慧";
//// Fix for CS0305: Specify both type parameters for IEmbeddingGenerationService<TValue, TEmbedding>
//var embeddingService = kernel.GetRequiredService<IEmbeddingGenerationService<string, float>>();
//var vector = await embeddingService.GenerateEmbeddingsAsync(new List<string> { text });

//// 聊天历史
//var history = new ChatHistory();
//// 连接 Milvus
//var milvusClient = new MilvusClient("localhost");
//string collectionName = "my_collection";

//// 假设已创建集合，字段有 id、text、embedding
//MilvusCollection collection = milvusClient.GetCollection(collectionName);
//var hasCollection = await milvusClient.HasCollectionAsync(collectionName);
//// 创建索引

//// 1. 用户输入转 embedding
//var queryVector = await embeddingService.GenerateEmbeddingsAsync(new List<string> { "爱国吗" });

//// 2. Milvus 检索最相似的 text
//var searchResult = await collection.SearchAsync(
//    "embedding",
//    new ReadOnlyMemory<float>[] { queryVector[0] },
//    SimilarityMetricType.L2,
//    limit: 10
//);



//// 找到 text 字段
//// 检索结果中取出 text 字段
//var textField = searchResult.FieldsData.FirstOrDefault(f => f.FieldName == "text");


//if (!hasCollection)
//{
//    await milvusClient.CreateCollectionAsync(
//                collectionName,
//                new[] {
//                FieldSchema.Create<long>("id", isPrimaryKey: true, autoId: true), // autoId: true
//                FieldSchema.CreateVarchar("text", vector[0].Length),
//                FieldSchema.CreateFloatVector("embedding", vector[0].Length)
//                }
//            );
//    await collection.CreateIndexAsync(
//    "embedding",                  // 向量字段名
//    IndexType.IvfFlat,           // 索引类型（常用有 IVF_FLAT、IVF_PQ、HNSW、AUTOINDEX）
//    SimilarityMetricType.L2,      // 距离度量方式（L2、IP等）
//   "nlist"  // 可选参数，视索引类型而定
//);
//}


//// 插入数据
//var res = await collection.InsertAsync(new FieldData[]
//{
//    FieldData.Create("text", new[] { text }),
//    FieldData.CreateFloatVector("embedding", new[] { vector[0] })
//});


//Console.WriteLine("Insert result: {0}", res.InsertCount);

//string? userInput;
//do
//{
//    Console.Write("User > ");
//    userInput = Console.ReadLine();
//    history.AddUserMessage(userInput);

//    // 流式输出
//    Console.Write("Assistant > ");
//    await foreach (var chunk in chatCompletionService.GetStreamingChatMessageContentsAsync(
//        history,
//        kernel: kernel))
//    {
//        if (!string.IsNullOrEmpty(chunk.Content))
//        {
//            Console.Write(chunk.Content);
//        }
//        // 你也可以根据 chunk.Role 做更细致的处理
//    }
//    Console.WriteLine();

// 记录最后一条消息到历史
// 这里可以拼接所有chunk的内容后再添加到history
// 简单起见，假设只记录最后一条
// history.AddMessage(result.Role, result.Content ?? string.Empty);
//} while (userInput is not null);